From: Colin Walters Date: Wed, 9 Jul 2025 19:21:56 +0000 (-0400) Subject: soft-reboot: Check for kernel argument changes X-Git-Tag: archive/raspbian/2025.7-2+rpi1^2^2~6^2~4^2~3^2 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https://%22%22/%22http:/www.example.com/cgi/%22https:/%22%22?a=commitdiff_plain;h=a0b387c33df6b4577c086e8fc90af3141bcd166f;p=ostree.git soft-reboot: Check for kernel argument changes This closes a drift gap possibility. Signed-off-by: Colin Walters --- diff --git a/src/libostree/ostree-deployment-private.h b/src/libostree/ostree-deployment-private.h index 367f68ea..2319ce08 100644 --- a/src/libostree/ostree-deployment-private.h +++ b/src/libostree/ostree-deployment-private.h @@ -68,4 +68,6 @@ void _ostree_deployment_set_overlay_initrds (OstreeDeployment *self, char **over char **_ostree_deployment_get_overlay_initrds (OstreeDeployment *self); +OstreeKernelArgs *_ostree_deployment_get_kargs (OstreeDeployment *self); + G_END_DECLS diff --git a/src/libostree/ostree-deployment.c b/src/libostree/ostree-deployment.c index a11efe55..73360d90 100644 --- a/src/libostree/ostree-deployment.c +++ b/src/libostree/ostree-deployment.c @@ -17,6 +17,7 @@ #include "config.h" +#include "ostree-bootconfig-parser.h" #include "ostree-deployment-private.h" #include "ostree.h" #include "otutil.h" @@ -493,3 +494,21 @@ ostree_deployment_is_soft_reboot_target (OstreeDeployment *self) { return self->soft_reboot_target; } + +/** + * ostree_deployment_get_kargs: + * @self: Deployment + * + * Returns: (transfer full) (nullable): Kernel arguments + */ +OstreeKernelArgs * +_ostree_deployment_get_kargs (OstreeDeployment *self) +{ + OstreeBootconfigParser *bootcfg = ostree_deployment_get_bootconfig (self); + if (!bootcfg) + return NULL; + const char *kargs = ostree_bootconfig_parser_get (bootcfg, "options"); + if (!kargs) + return NULL; + return ostree_kernel_args_from_string (kargs); +} diff --git a/src/libostree/ostree-deployment.h b/src/libostree/ostree-deployment.h index 7e923fe8..afa71fb2 100644 --- a/src/libostree/ostree-deployment.h +++ b/src/libostree/ostree-deployment.h @@ -18,6 +18,7 @@ #pragma once #include "ostree-bootconfig-parser.h" +#include "ostree-types.h" G_BEGIN_DECLS diff --git a/src/libostree/ostree-kernel-args-private.h b/src/libostree/ostree-kernel-args-private.h index 967676bb..56fb3c80 100644 --- a/src/libostree/ostree-kernel-args-private.h +++ b/src/libostree/ostree-kernel-args-private.h @@ -41,4 +41,6 @@ OstreeKernelArgsEntry *_ostree_kernel_args_entry_new (void); void _ostree_kernel_args_entry_value_free (OstreeKernelArgsEntry *e); +gboolean _ostree_kernel_args_equal (OstreeKernelArgs *a, OstreeKernelArgs *b); + G_END_DECLS diff --git a/src/libostree/ostree-kernel-args.c b/src/libostree/ostree-kernel-args.c index 57357a30..0d9973da 100644 --- a/src/libostree/ostree-kernel-args.c +++ b/src/libostree/ostree-kernel-args.c @@ -902,3 +902,24 @@ ostree_kernel_args_delete_if_present (OstreeKernelArgs *kargs, const char *arg, return ostree_kernel_args_delete (kargs, arg, error); return TRUE; } + +gboolean +_ostree_kernel_args_equal (OstreeKernelArgs *a, OstreeKernelArgs *b) +{ + if (a == b) + return TRUE; + if (a == NULL || b == NULL) + return FALSE; + if (a->order->len != b->order->len) + return FALSE; + for (guint i = 0; i < a->order->len; i++) + { + OstreeKernelArgsEntry *entry_a = g_ptr_array_index (a->order, i); + OstreeKernelArgsEntry *entry_b = g_ptr_array_index (b->order, i); + if (!g_str_equal (entry_a->key, entry_b->key)) + return FALSE; + if (g_strcmp0 (entry_a->value, entry_b->value) != 0) + return FALSE; + } + return TRUE; +} diff --git a/src/libostree/ostree-kernel-args.h b/src/libostree/ostree-kernel-args.h index b39dafd2..7f5569c7 100644 --- a/src/libostree/ostree-kernel-args.h +++ b/src/libostree/ostree-kernel-args.h @@ -24,8 +24,6 @@ G_BEGIN_DECLS -typedef struct _OstreeKernelArgs OstreeKernelArgs; - _OSTREE_PUBLIC void ostree_kernel_args_free (OstreeKernelArgs *kargs); diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 98d296a2..f2edef8e 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -39,6 +39,7 @@ #include "libglnx.h" #include "ostree-core-private.h" #include "ostree-deployment-private.h" +#include "ostree-kernel-args-private.h" #include "ostree-linuxfsutil.h" #include "ostree-repo-private.h" #include "ostree-sepolicy-private.h" @@ -4369,13 +4370,27 @@ gboolean ostree_sysroot_deployment_can_soft_reboot (OstreeSysroot *self, OstreeDeployment *deployment) { OstreeDeployment *booted_deployment = ostree_sysroot_get_booted_deployment (self); - if (booted_deployment != NULL) - { - const char *booted_bootcsum = ostree_deployment_get_bootcsum (booted_deployment); - const char *target_bootcsum = ostree_deployment_get_bootcsum (deployment); - return g_str_equal (booted_bootcsum, target_bootcsum); - } - return false; + if (booted_deployment == NULL) + return FALSE; + + const char *booted_bootcsum = ostree_deployment_get_bootcsum (booted_deployment); + const char *target_bootcsum = ostree_deployment_get_bootcsum (deployment); + if (!g_str_equal (booted_bootcsum, target_bootcsum)) + return FALSE; + + g_autoptr (OstreeKernelArgs) booted_kargs = _ostree_deployment_get_kargs (booted_deployment); + g_assert (booted_kargs); + + g_autoptr (OstreeKernelArgs) target_kargs = _ostree_deployment_get_kargs (deployment); + // The target kargs can be unset, which means use the merge kargs (same as booted, usually) + if (!target_kargs) + return TRUE; + + // Compare kargs without the ostree= entry, as that will vary per bootlink even for + // the same boot checksum. + g_assert (ostree_kernel_args_delete (booted_kargs, "ostree", NULL)); + g_assert (ostree_kernel_args_delete (target_kargs, "ostree", NULL)); + return _ostree_kernel_args_equal (booted_kargs, target_kargs); } static void diff --git a/src/libostree/ostree-types.h b/src/libostree/ostree-types.h index f3ba829c..4a44db0e 100644 --- a/src/libostree/ostree-types.h +++ b/src/libostree/ostree-types.h @@ -38,5 +38,6 @@ typedef struct OstreeMutableTree OstreeMutableTree; typedef struct OstreeRepoFile OstreeRepoFile; typedef struct _OstreeContentWriter OstreeContentWriter; typedef struct OstreeRemote OstreeRemote; +typedef struct _OstreeKernelArgs OstreeKernelArgs; G_END_DECLS diff --git a/tests/kolainst/destructive/soft-reboot.sh b/tests/kolainst/destructive/soft-reboot.sh index f5b23d48..f7b26b90 100755 --- a/tests/kolainst/destructive/soft-reboot.sh +++ b/tests/kolainst/destructive/soft-reboot.sh @@ -146,6 +146,15 @@ case "${AUTOPKGTEST_REBOOT_MARK:-}" in fatal "soft reboot prep with kernel change" fi assert_file_has_content_literal err.txt "different kernel state" + rm -vf err.txt + + rpm-ostree cleanup -p + + rpm-ostree kargs --append=foo=bar + if ostree admin prepare-soft-reboot 0 2>err.txt; then + fatal "soft reboot prep with kernel args change" + fi + assert_file_has_content_literal err.txt "different kernel state" echo "ok soft reboot all tests" ;;